package com.okami.serializable;


import java.io.*;

/**
 * @author: TanJingyu
 * @create: 2020-12-26 09:40
 **/
class Test {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        // dog 利用Serializable自动化
//        Dog dog = new Dog("王吉", 23);
//        ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("dog.file"));
//        out.writeObject(dog);
//
//        ObjectInputStream in = new ObjectInputStream(new FileInputStream("dog.file"));
//        Dog inDog = (Dog)in.readObject();
//        System.out.println(inDog);

        // 利用Externalizable，实现方法，手动干预
//        Pig pig = new Pig();
//        pig.setName("王吉");
//        pig.setAge(23);
//        ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("pig.file"));
//        out.writeObject(pig);
//
//        ObjectInputStream in = new ObjectInputStream(new FileInputStream("pig.file"));
//        Pig inPig = (Pig)in.readObject();
//        System.out.println(inPig);

        // 利用Serializable，添加规定的签名方法，进行干预。注意是自己添加，不是实现
//        Tiger tiger = new Tiger();
//        tiger.setName("王吉");
//        tiger.setAge(23);
//        ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("tiger.file"));
//        out.writeObject(tiger);
//
//        ObjectInputStream in = new ObjectInputStream(new FileInputStream("tiger.file"));
//        Tiger inTiger = (Tiger)in.readObject();
//        System.out.println(inTiger);
    }

    /**
     *  实现Serializable接口，实现自动序列化和反序列化，忽略age
     *  不会调用任何构造器，直接自动化完成字段的序列化和反序列化
     */
    private static class Dog implements Serializable{
        private String name;
        private transient Integer age;

        public Dog() {
            System.out.println("default construct");
        }

        public Dog(String name, Integer age) {
            System.out.println("all parameter construct");
            this.name = name;
            this.age = age;
        }

        @Override
        public String toString() {
            return "Dog{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }

        public Integer getAge() {
            return age;
        }

        public void setAge(Integer age) {
            this.age = age;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }
    }

    /**
     *  实现Externalizable接口，手动控制序列化和反序列化
     *  这时候会调用空参构造创建对象，然后调用实现的方法手动决定序列化和反序列化规则与字段
     */
    private static class Pig implements Externalizable {
        private String name;
        private Integer age;

        public Integer getAge() {
            return age;
        }

        public void setAge(Integer age) {
            this.age = age;
        }

        @Override
        public String toString() {
            return "Pig{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }

        public Pig() {
            System.out.println("default construct");
        }

        public Pig(String name, Integer age) {
            System.out.println("all parameter construct: " + name + " - " + age);
            this.name = name;
            this.age = age;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        @Override
        public void writeExternal(ObjectOutput out) throws IOException {
            out.writeObject(name);
        }

        @Override
        public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
            this.name = (String)in.readObject();
        }
    }

    /**
     * 添加规定的签名方法，进行干预。注意是自己添加，不是实现
     * 反序列化不会调用构造方法
     */
    private static class Tiger implements Serializable{
        private String name;
        private transient Integer age;

        /**
         * 手动添加的干预方法
         * 不可思议吧？是私有方法
         */
        private void writeObject(ObjectOutputStream stream) throws IOException {
            System.out.println("写--干预");
        }

        /**
         * 手动添加的干预方法
         * 不可思议吧？是私有方法
         */
        private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
            System.out.println("读--干预");
        }

        public Tiger() {
            System.out.println("default construct");
        }

        public Tiger(String name, Integer age) {
            System.out.println("all parameter construct");
            this.name = name;
            this.age = age;
        }

        @Override
        public String toString() {
            return "Tiger{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }

        public Integer getAge() {
            return age;
        }

        public void setAge(Integer age) {
            this.age = age;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }
    }
}
